/*
 * @Description: 
 * @Author: fhw
 * @Date: 2022-11-18 11:13:34
 */
import { Injectable, UseFilters } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { clone, equals, isEmpty, isNil } from 'ramda';
import { ChatUser } from 'src/chat_user/entities/chat_user.entity';
import { GroupChat } from 'src/group-chat/entities/group-chat.entity';
import { HttpExceptionFilter } from 'src/http-exception.filter';
import { getPagination, throwHttp } from 'src/utlis';
import { Repository } from 'typeorm';
import { CreateChatUserGroupParams } from './chat_user_group.module';
import { InviteAddChatUserGroupDto, ChatUserGroupPageDto, UpdateChatUserGroupDto } from './dto/chat_user_group.dto';
import { ChatUserGroup } from './entities/chat_user_group.entity';

@Injectable()
export class ChatUserGroupService {
  constructor(
    @InjectRepository(ChatUserGroup)
    private chatUserGroupRepository: Repository<ChatUserGroup>,
  ) { }

  @UseFilters(new HttpExceptionFilter())
  async getChatUserGroupPage(params: ChatUserGroupPageDto): Promise<PageResponse> {
    try {
      const { pageSize: size, pageNum: num, is_join, group_id, is_management } = params
      const { pageSize, pageNum } = getPagination({ pageSize: size, pageNum: num })
      const [userGrouplist, total] = await this.chatUserGroupRepository.findAndCount({
        where: { is_join, group_id, is_management },
        skip: pageNum * pageSize,
        take: pageSize,
        order: { createDate: 'DESC' },
        cache: true,
        relations: ['groupChat', 'chatUser']
      })
      const data = userGrouplist.map(item => {
        const chatUser = {
          id: item.chatUser.id,
          username: item.chatUser.username,
          headimgurl: item.chatUser.headimgurl,
          signature: item.chatUser.signature,
          account: item.chatUser.account,
        }
        if (item.groupChat) {
          delete item.groupChat.manager
        }
        return { ...item, chatUser, class: 2 }
      })
      return {
        data,
        total,
        pageSize,
        pageNum: pageNum * pageSize + 1,
      }
    } catch (error) {
      throwHttp(error.message)
    }
  }
  // 创建用户群聊表
  @UseFilters(new HttpExceptionFilter())
  async createChatUserGroup(params: CreateChatUserGroupParams[], { groupChat }: { groupChat: GroupChat }) {
    try {
      const chatUserGroupAll = params.map(item => {
        const chatUserGroup = new ChatUserGroup()
        chatUserGroup.group_id = item.group_id
        chatUserGroup.is_management = 0
        // chatUserGroup.is_join = isNil(item.is_join) ? (equals(Number(item.manager_id), item.chatUser.id) ? 1 : 0) : item.is_join
        // 默认同意加入
        chatUserGroup.is_join = 1
        // 绑定用户关系
        chatUserGroup.chatUser = item.chatUser
        // 绑定群聊信息
        chatUserGroup.groupChat = groupChat
        return chatUserGroup
      })
      const data = await this.chatUserGroupRepository.createQueryBuilder().insert().into(ChatUserGroup).values(chatUserGroupAll).execute()
      return data
    } catch (error) {
      throwHttp(`创建群聊失败，${error.message}`)
    }
  }
  // 更新用户群聊信息
  @UseFilters(new HttpExceptionFilter())
  async updateChatUserGroup(params: UpdateChatUserGroupDto) {
    try {
      const { userId, group_id, is_join, } = params
      const chatUserGroupInfo = await this.getChatUserGroupInfo({ userId, group_id })
      if (isNil(chatUserGroupInfo)) {
        throwHttp('当前用户群聊不存在')
      }
      const data = await this.chatUserGroupRepository
        .createQueryBuilder()
        .update('chat_user_group')
        .set({ is_join })
        .where('id = :id', { id: chatUserGroupInfo.id, userId, group_id })
        .execute()
      if (data.affected) {
        return data
      }
      throwHttp('更新失败')
    } catch (error) {
      throwHttp(error.message)
    }
  }
  // 删除用户群聊信息
  @UseFilters(new HttpExceptionFilter())
  async deleteChatUserGroup(params: UpdateChatUserGroupDto) {
    try {
      const data = await this.getChatUserGroupInfo(params)
      if (isNil(data)) {
        throwHttp('当前用户群聊不存在')
      }
      await this.chatUserGroupRepository.remove(data as ChatUserGroup);
      return '删除成功';
    } catch (error) {
      throwHttp(error.message)
    }
  }
  // 邀请加入群聊
  @UseFilters(new HttpExceptionFilter())
  async inviteAddChatUserGroup(params: InviteAddChatUserGroupDto, { groupChat, chatUser }: { groupChat: GroupChat; chatUser: ChatUser }): Promise<Boolean> {
    try {
      const { userId, group_id, inviterId } = params
      // 判断邀请人是否在群上
      const chatUserGroupInfo = await this.chatUserGroupRepository.findOne({
        where: { userId, group_id },
      })
      if (isNil(chatUserGroupInfo) || chatUserGroupInfo?.is_join !== 1) {
        throwHttp('邀请用户未加入该群聊')
      }
      // 判断被邀请用户在群上
      const inviterUserGrouInfo = await this.chatUserGroupRepository.findOne({
        where: { userId: inviterId, group_id },
      })
      if (inviterUserGrouInfo && inviterUserGrouInfo?.is_join === 1) {
        throwHttp('邀请用户已在群聊')
      }
      if (inviterUserGrouInfo && inviterUserGrouInfo?.is_join === 3) {
        throwHttp('邀请失败，邀请用户已申请加入群，等待管理员审核')
      }
      let isComplete: boolean = false
      // 判断是否已经邀请过并未同意或拒绝
      if (!isNil(inviterUserGrouInfo) && !isEmpty(inviterUserGrouInfo)) {
        const { affected } = await this.updateChatUserGroup({ userId: inviterId, group_id, is_join: 0 })
        if (affected) {
          isComplete = true
        }
      } else {
        const data = await this.createChatUserGroup([{ userId: inviterId, group_id, chatUser }], { groupChat })
        if (data) {
          isComplete = true
        }
      }
      return isComplete
    } catch (error) {
      throwHttp(error.message)
    }
  }

  // 获取用户群聊详情
  @UseFilters(new HttpExceptionFilter())
  async getChatUserGroupInfo(params: UpdateChatUserGroupDto): Promise<ChatUserGroup> {
    try {
      const data = await this.chatUserGroupRepository.findOne({
        where: params,
      })
      return data
    } catch (error) {
      throwHttp(error.message)
    }
  }
}
